package com.tipcp.equip.collect.service;

import com.tipcp.equip.collect.domain.Equip;
import com.tipcp.equip.collect.domain.EquipEsModel;
import com.tipcp.equip.collect.repository.EquipRepository;
import com.tipcp.equip.collect.service.strategy.CollectStrategyTypeEnum;
import com.tipcp.equip.collect.service.strategy.ReadTCPStrategy;
import com.tipcp.equip.collect.utils.IndexNameUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class EquipService {
    private final Map<String, Equip> equipMap = new ConcurrentHashMap<>();
    private final ExecutorService executorService;
    private final EquipRepository repository;

    @PostConstruct
    public void init() {
        addEquip(new Equip("1", "设备A", "Z139031", "127.0.0.1", 502, Arrays.asList("temperature", "pressure"/*,"humidity","vibration"*/), "TCP"));
        addEquip(new Equip("2", "设备B", "Z139032", "127.0.0.1", 502, Arrays.asList("temperature", "pressure", "humidity", "vibration"), "TCP"));
        addEquip(new Equip("3", "设备C", "Z139033", "127.0.0.1", 502, Arrays.asList("temperature", "pressure"/*,"humidity","vibration"*/), "TCP"));
    }

    public List<Equip> getAllEquips() {
        return new ArrayList<>(equipMap.values());
    }

    public void addEquip(Equip equip) {
        equipMap.put(equip.getId(), equip);
    }


    public EquipEsModel save(EquipEsModel equipEsModel) {
        return repository.save(equipEsModel);
    }

    public Optional<EquipEsModel> findById(String id) {
        return repository.findById(id);
    }

    public Iterable<EquipEsModel> findAll() {
        return repository.findAll();
    }

    public void deleteById(String id) {
        repository.deleteById(id);
    }

    public void collect() {
        getAllEquips().forEach(equip -> executorService.submit(() -> {
            List<EquipEsModel> equipEsModels = equip.getCollectParam().stream().map(param -> {
                ReadTCPStrategy strategy = CollectStrategyTypeEnum.getStrategy(param);
                return Objects.nonNull(strategy) ? strategy.readEquip(equip) : null;
            }).filter(Objects::nonNull).collect(Collectors.toList());
            repository.saveAllWithIndex(equipEsModels, IndexNameUtils.toSafeIndexName(equip.getEquipName()));
        }));
    }
}
